package org.skatiger.jrove.component.core;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;

import org.skatiger.jrove.JroveException;

public class FormatDate extends FormatBase {
    private static final String DATE = "date";
    private static final String TIME = "time";
    private static final String DATETIME = "both";

    private String type; // 'type' attribute
    private Object timeZone; // 'timeZone' attribute
    private String dateStyle; // 'dateStyle' attribute
    private String timeStyle; // 'timeStyle' attribute

    public String getTimeStyle() {
        return getPropertyValue("timeStyle", timeStyle);
    }

    public void setTimeStyle(String timeStyle) {
        this.timeStyle = timeStyle;
    }

    public String getDateStyle() {
        return getPropertyValue("dateStyle", dateStyle);
    }

    public void setDateStyle(String dateStyle) {
        this.dateStyle = dateStyle;
    }

    public void setTimeZone(Object timeZone) {
        this.timeZone = timeZone;
    }

    public Object getTimeZone() {
        return getPropertyValue("timeZone", timeZone);
    }

    public String getType() {
        return getPropertyValue("type", type);
    }

    public void setType(String type) {
        this.type = type;
    }

    private DateFormat createFormatter(Locale loc) throws JroveException {
        DateFormat formatter = null;
        if ((type == null) || DATE.equalsIgnoreCase(type)) {
            formatter = DateFormat.getDateInstance(
                    FormatUtil.getStyle(dateStyle), loc);
        } else if (TIME.equalsIgnoreCase(type)) {
            formatter = DateFormat.getTimeInstance(
                    FormatUtil.getStyle(timeStyle), loc);
        } else if (DATETIME.equalsIgnoreCase(type)) {
            formatter = DateFormat.getDateTimeInstance(
                    FormatUtil.getStyle(dateStyle),
                    FormatUtil.getStyle(timeStyle), loc);
        } else {
            throw new JroveException(("format date invalid type " + type));
        }

        return formatter;
    }

    @Override
    protected boolean isSupport(Class<?> clazz) {
        return Date.class.equals(clazz);
    }

    @Override
    protected String getFormatedValue() {
        String formatted = null;
        // Create formatter
        Locale locale = getLocale();
        Date value = (Date) getValue();
        if (locale != null) {
            DateFormat formatter = createFormatter(locale);
            // Apply pattern, if present
            String pattern = getPattern();
            if (pattern != null) {
                try {
                    ((SimpleDateFormat) formatter).applyPattern(pattern);
                } catch (ClassCastException cce) {
                    formatter = new SimpleDateFormat(pattern, locale);
                }
            }

            // Set time zone
            TimeZone tz = null;
            if ((timeZone instanceof String) && ((String) timeZone).equals("")) {
                timeZone = null;
            }
            if (timeZone != null) {
                if (timeZone instanceof String) {
                    tz = TimeZone.getTimeZone((String) timeZone);
                } else if (timeZone instanceof TimeZone) {
                    tz = (TimeZone) timeZone;
                } else {
                    throw new JroveException("format date bad timezone");
                }
            }
            if (tz != null) {
                formatter.setTimeZone(tz);
            }
            formatted = formatter.format(value);
        } else {
            // no formatting locale available, use Date.toString()
            formatted = value.toString();
        }
        return formatted;
    }
}
